package com.geepi.coremodule;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

/**
 * 作者：liaoyong on 2016/7/13 08:22
 * 邮箱：liaoyong@tuliu.com
 * 描述：文件操作工具类
 */
public class FileUtil {
    private static String TAG = "FileUtil";
    public static final long ONE_KB = 1024;
    public static final long ONE_MB = ONE_KB * ONE_KB;
    /**
     * The file copy buffer size (10 MB) （原为30MB，为更适合在手机上使用，将其改为10MB，by
     * Geek_Soledad)
     */
    private static final long FILE_COPY_BUFFER_SIZE = ONE_MB * 10;
    /**
     * 保存文件
     * @param bm
     * @param filePath
     * @throws IOException
     */
    public static void saveFile(Bitmap bm, String filePath) throws IOException {
        File myCaptureFile = new File(filePath);
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
        bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
        bos.flush();
        bos.close();
    }

    /**
     * 写文本文件
     * 在Android系统中，文件保存在 /data/data/PACKAGE_NAME/files 目录下
     * @param context
     * @param fileName
     */
    public static void write(Context context, String fileName, String content)
    {
        if( content == null )	content = "";

        try
        {
            FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
            fos.write( content.getBytes() );

            fos.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }



    public static void writeTextToFile(String strcontent, String strFilePath) {
        //每次写入时，都换行写
        String strContent = strcontent + "\n";
        try {
            File file = new File(strFilePath);
            if (!file.exists()) {
                Log.d("TestFile", "Create the file:" + strFilePath);
                file.createNewFile();
            }
            RandomAccessFile raf = new RandomAccessFile(file, "rw");
            raf.seek(file.length());
            raf.write(strContent.getBytes());
            raf.close();
        } catch (Exception e) {
            Log.e("TestFile", "Error on write File.");
        }
    }

    private static String readInStream(FileInputStream inStream)
    {
        try
        {
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[512];
            int length = -1;
            while((length = inStream.read(buffer)) != -1 )
            {
                outStream.write(buffer, 0, length);
            }

            outStream.close();
            inStream.close();
            return outStream.toString();
        }
        catch (IOException e)
        {
            Log.i("FileTest", e.getMessage());
        }
        return null;
    }

    public static File createFile( String folderPath, String fileName )
    {
        File file = new File(folderPath + File.separator + fileName);
        if(!file.exists()){
            file.getParentFile().mkdirs();
            try {
                file.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return file;
    }

    /**
     * 向手机写图片
     * @param buffer
     * @param folder
     * @param fileName
     * @return
     */
    public static boolean writeFile( byte[] buffer, String folder, String fileName )
    {
        boolean writeSucc = false;

        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);

        String folderPath = "";
        if( sdCardExist )
        {
            folderPath = Environment.getExternalStorageDirectory() + File.separator +  folder + File.separator;
        }
        else
        {
            writeSucc =false;
        }

        File fileDir = new File(folderPath);
        if(!fileDir.exists())
        {
            fileDir.mkdirs();
        }

        File file = new File( folderPath + fileName );
        FileOutputStream out = null;
        try
        {
            out = new FileOutputStream( file );
            out.write(buffer);
            writeSucc = true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try {out.close();} catch (IOException e) {e.printStackTrace();}
        }

        return writeSucc;
    }

    /**
     * 获取文件大小
     * @param filePath
     * @return
     */
    public static long getFileSize( String filePath )
    {
        long size = 0;

        File file = new File( filePath );
        if(file!=null && file.exists())
        {
            size = file.length();
        }

        return size;
    }

    /**
     * 获取文件大小
     * @param size 字节
     * @return
     */
    public static String getFileSize(long size)
    {
        if (size <= 0)	return "0";
        java.text.DecimalFormat df = new java.text.DecimalFormat("##.##");
        float temp = (float)size / 1024;
        if (temp >= 1024)
        {
            return df.format(temp / 1024) + "M";
        }
        else
        {
            return df.format(temp) + "K";
        }
    }

    /**
     * 转换文件大小
     * @param fileS
     * @return B/KB/MB/GB
     */
    public static String formatFileSize(long fileS) {
        java.text.DecimalFormat df = new java.text.DecimalFormat("#.00");
        String fileSizeString = "";
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "G";
        }
        return fileSizeString;
    }

    /**
     * 获取目录文件大小
     * @param dir
     * @return
     */
    public static long getDirSize(File dir) {

        if (dir == null) {
            return 0;
        }
        if (!dir.isDirectory()) {
            return 0;
        }
        long dirSize = 0;
        File[] files = dir.listFiles();
        for (File file : files) {
            if (file.isFile()) {
                dirSize += file.length();
            } else if (file.isDirectory()) {
                dirSize += file.length();
                dirSize += getDirSize(file); //递归调用继续统计
            }
        }
        return dirSize;
    }

    /**
     * 获取目录文件个数
     * @param dir
     * @return
     */
    public long getFileList(File dir){
        long count = 0;
        File[] files = dir.listFiles();
        count = files.length;
        for (File file : files) {
            if (file.isDirectory()) {
                count = count + getFileList(file);//递归
                count--;
            }
        }
        return count;
    }

    public static byte[] toBytes(InputStream in) throws IOException
    {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int ch;
        while ((ch = in.read()) != -1)
        {
            out.write(ch);
        }
        byte buffer[]=out.toByteArray();
        out.close();
        return buffer;
    }

    /**
     * 检查文件是否存在
     * @param filePath
     * @return
     */
    public static boolean checkFileExists(String filePath) {
        boolean status;
        if (!filePath.equals("")) {
            File newPath = new File(filePath);
            status = newPath.exists();
            newPath = null;
            System.gc();
        } else {
            status = false;
        }
        return status;

    }
    public static boolean deleteDir(String path){
        if (path == null || path.equals("") || path.equals("/"))
            return false;
        boolean success = true ;
        File file = new File(path) ;
        if(file.exists()){
            File[] list = file.listFiles() ;
            if(list != null){
                int len = list.length ;
                for(int i = 0 ; i < len ; ++i){
                    if(list[i].isDirectory()){
                        deleteDir(list[i].getPath()) ;
                    } else {
                        boolean ret = list[i].delete() ;
                        if(!ret){
                            success = false ;
                        }
                    }
                }
            }
        } else {
            success = false ;
        }
        if(success){
//	                file.delete() ;//只删除目录下的文件，不删除目录
        }
        return success ;
    }
    /**
     * 计算SD卡的剩余空间
     * @return 返回-1，说明没有安装sd卡
     */
    public static long getFreeDiskSpace() {
        String status = Environment.getExternalStorageState();
        long freeSpace = 0;
        if (status.equals(Environment.MEDIA_MOUNTED)) {
            try {
                File path = Environment.getExternalStorageDirectory();
                StatFs stat = new StatFs(path.getPath());
                long blockSize = stat.getBlockSize();
                long availableBlocks = stat.getAvailableBlocks();
                freeSpace = availableBlocks * blockSize / 1024;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            return -1;
        }
        return (freeSpace);
    }

    /**
     * 新建目录
     * @param directoryName
     * @return
     */
    public static boolean createDirectory(String directoryName) {
        boolean status;
        if (!directoryName.equals("")) {
            File path = Environment.getExternalStorageDirectory();
            File newPath = new File(path.toString() + directoryName);
            status = newPath.mkdir();
            status = true;
        } else
            status = false;
        return status;
    }

    /**
     * 检查是否安装SD卡
     * @return
     */
    public static boolean checkSaveLocationExists() {
        String sDCardStatus = Environment.getExternalStorageState();
        boolean status;
        if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
            status = true;
        } else
            status = false;
        return status;
    }

    /**
     * 删除目录(包括：目录里的所有文件)
     * @param fileName
     * @return
     */
    public static boolean deleteDirectory(String fileName) {
        boolean status;
        SecurityManager checker = new SecurityManager();

        if (!fileName.equals("")) {

            File path = Environment.getExternalStorageDirectory();
            File newPath = new File(path.toString() + fileName);
            checker.checkDelete(newPath.toString());
            if (newPath.isDirectory()) {
                String[] listfile = newPath.list();
                // delete all files within the specified directory and then
                // delete the directory
                try {
                    for (int i = 0; i < listfile.length; i++) {
                        File deletedFile = new File(newPath.toString() + "/"
                                + listfile[i].toString());
                        deletedFile.delete();
                    }
                    newPath.delete();
                    status = true;
                } catch (Exception e) {
                    e.printStackTrace();
                    status = false;
                }

            } else
                status = false;
        } else
            status = false;
        return status;
    }

    /**
     * 删除文件
     * @param filePath
     * @return
     */
    public static boolean deleteFile(String filePath) {
        if (TextUtils.isEmpty(filePath))
            return false;

        boolean status;
        SecurityManager checker = new SecurityManager();
        File newPath = new File(filePath);
        checker.checkDelete(newPath.toString());
        if (newPath.isFile()) {
            try {
                newPath.delete();
                status = true;
            } catch (SecurityException se) {
                se.printStackTrace();
                status = false;
            }
        } else {
            status = false;
        }
        return status;
    }

    /**
     * 用正则判断是否要新建文件夹以及执行新建
     *
     * @param absolutePath
     *            String
     * @return boolean
     * @throws MalformedURLException
     */
    public static boolean mkDirs(String absolutePath) throws MalformedURLException {
        String dirName = absolutePath.substring(0,
                absolutePath.lastIndexOf("/") + 1);
        if (!isDirNameValid(dirName)) {
            return false;
        }

        File file = new File(dirName);
        if (!file.exists()) {
            try {
                boolean result = file.mkdirs();
                if (result) {
                    return true;
                } else {
                    return false;
                }
            } catch (Exception e) {
                // TODO: handle exception
                return false;
            }
        }

        return true;
    }

    public static boolean isDirNameValid(String dirName) {
        return true;
    }

    public static boolean isFileNameValid(String fileName) {
        try {
            Pattern pat = Pattern
                    .compile("^([a-z|A-Z|\\d]+)[.]{1}([A-Z|a-z]{3,4})$");
            Matcher mat = pat.matcher(fileName);
            return mat.matches();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            Log.v(TAG, "文件名无效！");
            return false;
        }
    }

    /**
     * 根据文件类实体来删除单个文件或整个文件夹
     *
     * @param file
     *            File
     * @return isFileDeleteSuccess boolean
     */
    public static boolean deleteFile(File file) {
        boolean isFileDeleteSuccess = false;
        if (file.exists()) {
            if (file.isDirectory()) {
                for (File child : file.listFiles()) {
                    isFileDeleteSuccess &= deleteFile(child);
                }
                isFileDeleteSuccess &= file.delete(); // Delete empty directory.
            }
            if (file.isFile()) {
                isFileDeleteSuccess &= file.delete();
            }
            if (!isFileDeleteSuccess) {
                Log.e(null, "Delete failed;");
            }
            return isFileDeleteSuccess;
        } else {
            Log.e(null, "File does not exist.");
            return false;
        }
    }

    /**
     * 文件路径是否有效
     * 指定路径的文件是否存在、为文件实体并且可读
     *
     * @param filePath
     * @return
     * @author zhaoyun
     */
    public static boolean isFilePathExist(String filePath) {
        if (TextUtils.isEmpty(filePath)) {
            return false;
        }
        File file = new File(filePath);
        boolean isFilePathExist = file.exists() && file.isFile() && file.canRead();
        file = null;
        System.gc();
        return isFilePathExist;
    }
}